package utils

import (
	"bufio"
	"errors"
	"io/fs"
	"io/ioutil"
	"log"
	"os"
	"sort"
)

//参考：https://blog.csdn.net/lady_killer9/article/details/116454527
/*

// 必须指定O_RDONLY、O_WRONLY或O_RDWR中的一个。
O_RDONLY int = syscall.O_RDONLY // 只读
O_WRONLY int = syscall.O_WRONLY // 只写
O_RDWR   int = syscall.O_RDWR   // 读写
// 其余的值可以控制行为。
O_APPEND int = syscall.O_APPEND // 追加
O_CREATE int = syscall.O_CREAT  // 创建如果不存在
O_EXCL   int = syscall.O_EXCL   // 和O_CREATE一起使用, 文件必须不存在
O_SYNC   int = syscall.O_SYNC   // 同步I/O
O_TRUNC  int = syscall.O_TRUNC  // 清空
*/

func WriteStrings(filePath string, content string, mode int) error {
	_ = OpenCreate(filePath, 0666)
	switch mode {
	case 1:
		mode = os.O_WRONLY // 只写
	case 2:
		mode = os.O_RDWR // 读写
	default:
		mode = os.O_APPEND // 追加
	}
	file, err := os.OpenFile(filePath, mode, 0666)
	if err != nil {
		return err
	}
	defer file.Close()
	_, err = file.WriteString(content)
	if err != nil {
		return err
	}
	return nil
}

/*
_ = OpenCreate("./file.txt",0666)
_ = OpenCreate(".//?/file.txt",0666)

2021/05/06 16:50:41 error OpenCreate.//?/file.txt
*/
func OpenCreate(filePath string, perm os.FileMode) error {
	_, err := os.OpenFile(filePath, os.O_CREATE, perm)
	if err != nil {
		log.Fatal("error OpenCreate：", filePath)
		return err
	}
	return nil
}

/*
调用：
file :="./file.txt"
datas, _ := utils.ReadWithScanner(file)

	for _, data := range datas {
		fmt.Print(data, "\r\n")
	}

输出
1177063116900884481
88585187
1373391637
*/
func ReadWithScanner(filepath string) ([]string, error) {
	file, err := os.Open(filepath)
	if err != nil {
		return nil, err
	}
	defer file.Close()
	scanner := bufio.NewScanner(file)
	res := make([]string, 1)
	for scanner.Scan() {
		res = append(res, scanner.Text())
	}
	return res, nil
}

/*
调用示例
data,_ := utils.ReadFile("./file.txt")
fmt.Printf(" data:%c,len:%v",data,len(data))
结果
 data:[l a d y _ k i l l e r 7
 l a d y _ k i l l e r 8
 l a d y _ k i l l e r 9
],len:42
*/
func ReadFile(filepath string) ([]byte, error) {
	file, err := os.Open(filepath)
	if err != nil {
		return nil, err
	}
	defer file.Close()
	fileCon, err := ioutil.ReadFile(filepath)
	if err != nil {
		return nil, err
	}
	return fileCon, nil
}

// -----------------------判断文件或目录是否存在-------------
/**
	调用示例：
	ok := CheckFileIsExist("./file.txt")
	fmt.Println("./file.txt存在？",ok)
	ok = CheckFileIsExist("../lady_killer9")
	fmt.Println("../lady_killer9存在？",ok)
	输出：
	./file.txt存在？ true
	../lady_killer9存在？ false
**/
func CheckFileIsExist(filename string) bool {
	var exist = true
	if _, err := os.Stat(filename); os.IsNotExist(err) {
		exist = false
	}
	return exist
}

// -----------------------------读取目录-----------------------
func readDir(dirname string, name, size, time bool) ([]fs.FileInfo, error) {
	f, err := os.Open(dirname)
	if err != nil {
		return nil, err
	}
	list, err := f.Readdir(-1)
	f.Close()
	if err != nil {
		return nil, err
	}
	if name == false && size == false && time == false {
		return nil, errors.New("you must choose a way for ordering")
	}
	if name {
		sort.Slice(list, func(i, j int) bool { return list[i].Name() < list[j].Name() })
	} else if size {
		sort.Slice(list, func(i, j int) bool { return list[i].Size() < list[j].Size() })
	} else if time {
		sort.Slice(list, func(i, j int) bool { return list[i].ModTime().Before(list[j].ModTime()) })
	}
	return list, nil
}

/*
通过名字排序
调用示例：
lists, _ := utils.ReadDirByName("./data/daoru/")
fmt.Println("------按照名字排序--------")

	for _, lst := range lists {
		fmt.Print(lst.Name(), "\r\n")
	}

输出：
------按照名字排序--------
2.txt
4.txt
*/
func ReadDirByName(dirname string) ([]fs.FileInfo, error) {
	return readDir(dirname, true, false, false)
}

// 通过大小排序
func ReadDirBySize(dirname string) ([]fs.FileInfo, error) {
	return readDir(dirname, false, true, false)
}

// 通过最后修改时间排序
func ReadDirByTime(dirname string) ([]fs.FileInfo, error) {
	return readDir(dirname, false, false, true)
}
